package com.apache.auditRule.service.impl;

import java.lang.reflect.Method;
import java.util.List;

import com.apache.api.vo.ParamsVo;
import com.apache.auditRule.entity.Audit;
import com.apache.auditRule.entity.AuditRule;
import com.apache.auditRule.manager.AuditManager;
import com.apache.auditRule.manager.AuditRuleManager;
import com.apache.cache.util.Validator;
import com.apache.database.db.IDao;
import com.apache.database.model.MethodParam;
import com.apache.database.model.Page;
import com.apache.exception.BusinessException;
import com.apache.member.common.ConstantData;
import com.apache.member.common.DateUtil;
import com.apache.member.entity.CompareVo;
import com.apache.member.entity.Member;
import com.apache.member.entity.MemberRole;
import com.apache.member.manager.MemberManager;
import com.apache.tools.DateUtils;

public class AuditManagerImpl implements AuditManager {

	protected IDao auditDao;
	protected final String entityName = "com.apache.auditRule.entity.Audit";
	protected final String memberModifyEntityName = "com.apache.finance.entity.MemberModify";
	//	protected final String memberEntity = "com.apache.member.entity.Member";
	//	protected final String memberTempEntity = "com.apache.member.entity.MemberTemp";
	//	protected final String paymentRegAuditVo = "com.apache.member.entity.PaymentRegAuditVo";
	//	protected final String paymentReg = "com.apache.member.entity.PaymentReg";

	private AuditRuleManager auditRuleManager;

	private MemberManager memberManager;

	public MemberManager getMemberManager() {
		return memberManager;
	}

	public void setMemberManager(MemberManager memberManager) {
		this.memberManager = memberManager;
	}

	public AuditRuleManager getAuditRuleManager() {
		return auditRuleManager;
	}

	public void setAuditRuleManager(AuditRuleManager auditRuleManager) {
		this.auditRuleManager = auditRuleManager;
	}

	public void setAuditDao(IDao auditDao) {
		this.auditDao = auditDao;
	}

	public String saveInfo(ParamsVo<Audit> vo) throws BusinessException {
		Audit audit = vo.getObj();
		String infoId = Validator.generate();
		//定义对象缓存KEY,如果不需要缓存对象请不要对变量赋值，如果要缓存对象建议使用infoId
		String cacheKey = "";
		//String cacheKey="audit_"+infoId;
		audit.setAuditsId(infoId);
		MethodParam param = new MethodParam("Audit", cacheKey, "", entityName);
		param.setVaule(audit);
		if (auditDao.insert(param)) {
			return infoId;
		}
		return "";
	}

	public boolean editAudit(ParamsVo<Audit> vo) throws BusinessException {

		Audit audit = vo.getObj();
		if (Validator.isNotNull(audit.getAuditsId())) {
			String cacheKey = "";
			//String cacheKey="member_"+member.getMemberId();
			MethodParam param = new MethodParam("Audit", cacheKey, "", entityName);
			audit.setUpdateTime(DateUtils.getNow());
			param.setVaule(audit);
			return auditDao.edit(param);
		}
		return false;
	}

	/**
	 * 公用的审核方法--核心
	 *   
	 * @see com.apache.api.manager.BaseManager#editInfo(com.apache.api.vo.ParamsVo)
	 */
	public boolean editInfo(ParamsVo<Audit> vo) {
		String auditStatus = "";
		//会员认证审核方法
		if ("member-identify-audit".equals(vo.getMethodKey())) {
			return identifyAudit(vo, auditStatus);
		}
		//普通用户申请成为会员的方法
		if ("addMember-audit".equals(vo.getMethodKey())) {
			return addMemberAudit(vo, auditStatus);
		}
		if ("addMemberAndRoles-audit".equals(vo.getMethodKey())) {
			return this.addMemberAndRolesAudit(vo, auditStatus);
		}
		if ("editMemberAndRoles-audit".equals(vo.getMethodKey())) {
			return this.addMemberAndRolesAudit(vo, auditStatus);
		}
//		if ("pro-audit".equals(vo.getMethodKey())) {
//			return this.proAudit(vo, auditStatus);
//		}
//		if ("deal-audit".equals(vo.getMethodKey())) {
//			return this.dealAudit(vo, auditStatus);
//		}

		Audit audit = vo.getObj();
		if (Validator.isNotNull(audit.getAuditsId())) {
			String cacheKey = "";
			audit.setAuditsStatus(auditStatus);
			//String cacheKey="audit_"+audit.getAuditId();
			MethodParam param = new MethodParam("Audit", cacheKey, "", entityName);
			param.setVaule(audit);
			return auditDao.edit(param);
		}
		return false;
	}

	public boolean deleteInfo(ParamsVo<Audit> vo) throws BusinessException {
		String infoId = vo.getInfoId();
		if (Validator.isNull(infoId)) {
			return false;
		}
		String cacheKey = "";
		//String cacheKey="audit_"+infoId;
		String mark = Validator.getDefaultStr(String.valueOf(vo.getParams("isDelete")), "true");
		MethodParam param = new MethodParam("ById", cacheKey, "", entityName);
		param.setInfoId(infoId);
		Audit info = (Audit) auditDao.selectById(param);
		if (Validator.isEmpty(info)) {
			return false;
		}
		param.setVaule(info);//此处需要先将状态值赋值为删除状态
		if ("false".equals(mark)) {//逻辑删除
			param.setKey("Audit");
			return auditDao.edit(param);
		} else {
			param.setParams("auditId", infoId);
			param.setDelete(true);
			return auditDao.delete(param);
		}
	}

	public Object getInfoById(ParamsVo<Audit> vo) {
		String infoId = vo.getInfoId();
		String cacheKey = "";
		//String cacheKey="audit_"+infoId;
		if (Validator.isNull(infoId)) {
			return null;
		}
		MethodParam param = new MethodParam("ById", cacheKey, "", entityName);
		param.setInfoId(infoId);
		return auditDao.selectById(param);
	}

	public Object execute(ParamsVo<Audit> vo) {
		// 获取待审核列表
		if ("getAuditList".equals(vo.getMethodKey())) {
			return this.getAuditList(vo);
		}

		return null;
	}

	public Page getPageInfo(ParamsVo<Audit> vo) {

		MethodParam param = setMethodParams(vo, 2);
		int pageSize = Integer.valueOf(Validator.getDefaultStr(String.valueOf(vo.getParams("pageSize")), "10"));
		int pageIndex = Integer.valueOf(Validator.getDefaultStr(String.valueOf(vo.getParams("pageIndex")), "1"));
		param.setPageIndex(pageIndex);
		param.setPageSize(pageSize);
		Page page = auditDao.pageSelect(param);
		return page;
	}

	public Page getAuditList(ParamsVo<Audit> vo) {
		MethodParam param = new MethodParam("AuditList", "", "", entityName);
		param.setParams("tableName", String.valueOf(vo.getParams("tableName")));
		param.setParams("colName", String.valueOf(vo.getParams("colName")));
		param.setParams("pageSize", String.valueOf(vo.getParams("pageSize")));
		param.setParams("pageIndex", String.valueOf(vo.getParams("pageIndex")));
		Audit audit = new Audit();
		audit = vo.getObj();
		if (!Validator.isEmpty(audit)) {
			if (Validator.isNotNull(audit.getAuditType())) {
				param.setParams("auditType", audit.getAuditType());
			}
			param.setParams("checkUser", audit.getCheckUser());
			param.setParams("auditsStatus", audit.getAuditsStatus());
			param.setParams("num", audit.getNum());

		}
		int pageSize = Integer.valueOf(Validator.getDefaultStr(String.valueOf(vo.getParams("pageSize")), "10"));
		int pageIndex = Integer.valueOf(Validator.getDefaultStr(String.valueOf(vo.getParams("pageIndex")), "1"));
		param.setPageIndex(pageIndex);
		param.setPageSize(pageSize);
		Page page = auditDao.pageSelect(param);
		return page;
	}

	public List<Audit> getList(ParamsVo<Audit> vo) {
		MethodParam param = setMethodParams(vo, 2);
		//param.setOrderby(" update_time desc, create_time desc ");
		param.setParams("orderby", "order by update_time desc, create_time desc");
		return auditDao.select(param);
	}

	public long countInfo(ParamsVo<Audit> vo) {
		MethodParam param = setMethodParams(vo, 1);
		return auditDao.count(param);
	}

	private MethodParam setMethodParams(ParamsVo<Audit> vo, int type) {
		String methodKey = Validator.getDefaultStr(vo.getMethodKey(), "ByProperty");
		StringBuffer sb = new StringBuffer(auditDao.getSql(type));
		MethodParam param = new MethodParam(methodKey, "", "", entityName);
		Audit audit = vo.getObj();
		if (!Validator.isEmpty(audit)) {

			if (Validator.isNotNull(audit.getTableName())) {
				sb.append(" and tableName = :tableName");
				param.setParams("tableName", audit.getTableName());
			}
			if (Validator.isNotNull(audit.getColName())) {
				sb.append(" and colName = :colName");
				param.setParams("colName", audit.getColName());
			}
			if (Validator.isNotNull(audit.getPid())) {
				sb.append(" and pid = :pid");
				param.setParams("pid", audit.getPid());
			}
			if (Validator.isNotNull(audit.getAuditType())) {
				param.setParams("auditType", audit.getAuditType());
			}
			if (Validator.isNotNull(audit.getCheckUser())) {
				sb.append(" and checkUser = :checkUser");
				param.setParams("checkUser", audit.getCheckUser());
			}
			if (Validator.isNotNull(audit.getNextUser())) {
				sb.append(" and nextUser = :nextUser");
				param.setParams("nextUser", audit.getNextUser());
			}
			if (Validator.isNotNull(audit.getNum())) {
				sb.append(" and num = :num");
				param.setParams("num", audit.getNum());
			}
			if (Validator.isNotNull(audit.getAuditsStatus())) {
				sb.append(" and auditsStatus = :auditsStatus");
				param.setParams("auditsStatus", audit.getAuditsStatus());
			}
			if (Validator.isNotNull(audit.getAuditOpinion())) {
				sb.append(" and auditOpinion = :auditOpinion");
				param.setParams("auditOpinion", audit.getAuditOpinion());
			}
			if (Validator.isNotNull(audit.getCreateUserEname())) {
				sb.append(" and createUserEname = :createUserEname");
				param.setParams("createUserEname", audit.getCreateUserEname());
			}
			if (Validator.isNotNull(audit.getCreateTime())) {
				sb.append(" and createTime = :createTime");
				param.setParams("createTime", audit.getCreateTime());
			}
			if (Validator.isNotNull(audit.getUpdateUserEname())) {
				sb.append(" and updateUserEname = :updateUserEname");
				param.setParams("updateUserEname", audit.getUpdateUserEname());
			}
			if (Validator.isNotNull(audit.getUpdateTime())) {
				sb.append(" and updateTime = :updateTime");
				param.setParams("updateTime", audit.getUpdateTime());
			}
			if (Validator.isNotNull(audit.getProId())) {
				param.setParams("proId", audit.getProId());
			}
			if (Validator.isNotNull(audit.getTaskName())) {
				param.setParams("taskName", audit.getTaskName());
			}
		}
		param.setSqlStr(sb.toString());
		return param;
	}

	/**
	 * 返回Audit和payment
	 * @param vo
	 * @return
	 */
	public List<Object> getAuditAndPayment(ParamsVo<Audit> vo) {
		String cacheKey = "";
		MethodParam param = new MethodParam("ByPaymentRegAndAudit", cacheKey, "", "com.apache.member.entity.PaymentReg");
		param.setParams("auditType", (String) vo.getParams("auditType"));
		param.setParams("checkUser", (String) vo.getParams("checkUser"));
		return auditDao.select(param);
	}

	/**
	 * 审核通过操作的步骤
	 *  1 更新t_AUDIT  状态、意见、上传附件等 
	 *  2如果审核通过。
	 *             如果下一审核人为00,更新table_name 下的status91
	 *             如果下一审核人不为00，需要查通过NEXT_USER(t_audit_rule DE RULE_ID)看t_audit_rule里的下一个记录    insert 到t_audit表中一条记录
	 *  3如果审核不通过 
	 *	           如果上一审核人为空，更新table_name下的status 90    
	 *	            如果上一审核人不为空，要查通过NEXT_USER(t_audit_rule DE RULE_ID)看t_audit_rule里的下一个记录    insert 到t_audit表中一条记录
	 * @param vo
	 * @return
	 * @throws BusinessException
	 */
	public boolean editIdentifyPass(ParamsVo<Audit> vo, Object entity) throws Exception {
		boolean flag = false;
		Audit audit = vo.getObj();
		String cacheKey = "";
		MethodParam param = new MethodParam("Audit", cacheKey, "", entityName);
		audit.setUpdateTime(DateUtil.getNowTime());
		//		LoginUser loginUser = (LoginUser) vo.getParams("loginUser");
		audit.setUpdateUserEname(String.valueOf(vo.getParams("userEname")));
		param.setVaule(audit);

		boolean auditFlag = auditDao.edit(param);
		if (auditFlag) {
			//2、判断t_audit下一审核人是否为00
			String table_name = audit.getTableName();
			String col_name = audit.getColName();
			String pid = audit.getPid();
			AuditRule auditRule = new AuditRule();
			ParamsVo<AuditRule> ruleVo = new ParamsVo<AuditRule>();
			MethodParam insertAuditParams = new MethodParam("Audit", cacheKey, "", entityName);
			Audit newAudit = new Audit();
			String auditId = Validator.generate();
			String isPass = (String) vo.getParams("auditFlag");
			String nextUser = audit.getNextUser();

			MethodParam paramForUpdate = new MethodParam("ByParams", cacheKey, "", entityName);
			paramForUpdate.setParams("table_name", table_name);
			paramForUpdate.setParams("col_name", col_name);
			paramForUpdate.setParams("pid", pid);
			if ("T".equals(isPass)) {
				nextUser = audit.getNextUser();
				ruleVo.setInfoId(nextUser);

			}
			if ("F".equals(isPass)) {
				nextUser = audit.getLastUser();
				ruleVo.setInfoId(nextUser);
			}
			paramForUpdate.setParams("joinsql", this.joinSql(entity, paramForUpdate));
			if (ConstantData.FLAG00.equals(nextUser) || Validator.isNull(nextUser)) {
				//一次审核
				if (!Validator.isEmpty(entity)) {
					flag = auditDao.edit(paramForUpdate);
				} else {
					flag = true;
				}
			} else {
				//多次审核
				auditRule = (AuditRule) auditRuleManager.getInfoById(ruleVo);
				newAudit.setAuditsId(auditId);
				newAudit.setCheckUser(auditRule.getCheckUser());
				newAudit.setPid(pid);
				newAudit.setNextUser(auditRule.getNext());
				newAudit.setLastUser(auditRule.getLast());
				newAudit.setTableName(table_name);
				newAudit.setAuditsStatus(ConstantData.AuditStatus.AUDITING);
				newAudit.setNum(auditRule.getNum());
				newAudit.setAuditType(auditRule.getAuditType());
				newAudit.setColName(col_name);
				newAudit.setCreateTime(DateUtil.getNowTime());
				newAudit.setUpdateTime(DateUtil.getNowTime());
				newAudit.setCreateUserEname(String.valueOf(vo.getParams("userEname")));
				newAudit.setUpdateUserEname(String.valueOf(vo.getParams("userEname")));
				insertAuditParams.setVaule(newAudit);
				flag = auditDao.insert(insertAuditParams);
			}
		}

		return flag;
	}

	/**
	 * 封装update 实体 set 的语句
	 * description:  
	 * @param entity
	 * @param paramMap
	 * @return
	 * @throws Exception  
	 * @author cbqiu 
	 * @update 2015-6-25
	 */
	private String joinSql(Object entity, MethodParam paramMap) throws Exception {
		String sql = "";
		Class c = entity.getClass();
		Method[] methods = c.getMethods();
		for (Method m : methods) {
			String mName = m.getName();
			if (mName.startsWith("get") && !mName.startsWith("getClass")) {
				String fieldName = mName.substring(3, mName.length());
				Object value = m.invoke(entity, null);
				if (!Validator.isEmpty(value)) {
					if (Validator.isNotNull(sql)) {

						sql += "," + this.setObject(fieldName) + "='" + value + "'";
					} else {
						sql += this.setObject(fieldName) + "='" + value + "'";

					}
				}

			}
		}
		return sql;
	}

	private static String setObject(Object o) {
		String name = (String) o;

		StringBuffer sb = new StringBuffer();

		String[] ss = name.split("(?=[A-Z])");

		for (int j = 0; j < ss.length; j++) {
			if ("".equals(ss[j])) {
				continue;
			}
			if (j == ss.length - 1)
				sb.append(ss[j].toLowerCase());
			else
				sb.append(ss[j].toLowerCase() + "_");
		}

		return sb.toString();
	}

	public static void main(String[] args) {
		String test = "MemberId";
		System.out.println(setObject(test));
		;

	}

	@Override
	public List<Object> getAuditAndMember(ParamsVo<Audit> vo) {

		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<CompareVo> getOneColumn(ParamsVo<CompareVo> vo) {

		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<CompareVo> getTableColumn(ParamsVo<CompareVo> vo) {

		// TODO Auto-generated method stub
		return null;
	}

	private boolean identifyAudit(ParamsVo<Audit> vo, String auditStatus) {
		Member member = new Member();
		auditStatus = ConstantData.AuditStatus.AUDIT_NOPASS;
		Audit audit = vo.getObj();
		String isPass = (String) vo.getParams("auditFlag");
		if (isPass.equals(ConstantData.FLAG_OK)) {
			auditStatus = ConstantData.AuditStatus.AUDIT_PASS;
			member.setMemberLevel(ConstantData.MemberLevel.IDENTIFY);

		} else if (isPass.equals(ConstantData.FLAG_FALSE)) {
			auditStatus = ConstantData.AuditStatus.AUDIT_NOPASS;
		}
		try {
			audit.setAuditsStatus(auditStatus);
			vo.setObj(audit);
			member.setUpdateTime(DateUtil.getNowTime());
			member.setAuditStatus(auditStatus);
			boolean rs = this.editIdentifyPass(vo, member);
			return rs;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	private boolean addMemberAudit(ParamsVo<Audit> vo, String auditStatus) {
		Member member = new Member();
		auditStatus = ConstantData.AuditStatus.AUDIT_NOPASS;
		Audit audit = vo.getObj();
		String isPass = (String) vo.getParams("auditFlag");
		if (isPass.equals(ConstantData.FLAG_OK)) {
			member.setMemberLevel(ConstantData.MemberLevel.NORMAL);
			auditStatus = ConstantData.AuditStatus.AUDIT_PASS;
			member.setStatus(ConstantData.UserStatus.START);

		} else if (isPass.equals(ConstantData.FLAG_FALSE)) {
			auditStatus = ConstantData.AuditStatus.AUDIT_NOPASS;
		}
		try {
			audit.setAuditsStatus(auditStatus);
			vo.setObj(audit);
			member.setUpdateTime(DateUtil.getNowTime());
			member.setAuditStatus(auditStatus);
			boolean rs = this.editIdentifyPass(vo, member);
			return rs;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	private boolean addMemberAndRolesAudit(ParamsVo<Audit> vo, String auditStatus) {
		MemberRole memberRole = new MemberRole();
		auditStatus = ConstantData.AuditStatus.AUDIT_NOPASS;
		Audit audit = vo.getObj();
		String isPass = (String) vo.getParams("auditFlag");
		if (isPass.equals(ConstantData.FLAG_OK)) {
			auditStatus = ConstantData.AuditStatus.AUDIT_PASS;

		} else if (isPass.equals(ConstantData.FLAG_FALSE)) {
			auditStatus = ConstantData.AuditStatus.AUDIT_NOPASS;
		}
		try {
			audit.setAuditsStatus(auditStatus);
			vo.setObj(audit);
			memberRole.setAuditStatus(auditStatus);
			boolean rs = this.editIdentifyPass(vo, memberRole);
			return rs;

		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

//	private boolean proAudit(ParamsVo<Audit> vo, String auditStatus) {
//		TrpPro pro = new TrpPro();
//		auditStatus = ConstantData.AuditStatus.AUDIT_NOPASS;
//		Audit audit = vo.getObj();
//		String isPass = (String) vo.getParams("auditFlag");
//		if (isPass.equals(ConstantData.FLAG_OK)) {
//			auditStatus = ConstantData.AuditStatus.AUDIT_PASS;
//
//		} else if (isPass.equals(ConstantData.FLAG_FALSE)) {
//			auditStatus = ConstantData.AuditStatus.AUDIT_NOPASS;
//		}
//		try {
//			audit.setAuditsStatus(auditStatus);
//			vo.setObj(audit);
//			pro.setProStatus(String.valueOf(vo.getParams("proStatus")));
//			boolean rs = false;
//			if (Validator.isEmpty(pro)) {
//				rs = this.editIdentifyPass(vo, null);
//
//			} else {
//				rs = this.editIdentifyPass(vo, pro);
//			}
//			return rs;
//
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		return false;
//	}
//
//	private boolean dealAudit(ParamsVo<Audit> vo, String auditStatus) {
//		TrpDeal deal = new TrpDeal();
//		auditStatus = ConstantData.AuditStatus.AUDIT_NOPASS;
//		Audit audit = vo.getObj();
//		String isPass = (String) vo.getParams("auditFlag");
//		if (isPass.equals(ConstantData.FLAG_OK)) {
//			auditStatus = ConstantData.AuditStatus.AUDIT_PASS;
//
//		} else if (isPass.equals(ConstantData.FLAG_FALSE)) {
//			auditStatus = ConstantData.AuditStatus.AUDIT_NOPASS;
//		}
//		try {
//			audit.setAuditsStatus(auditStatus);
//			vo.setObj(audit);
//			//			pro.setProStatus(String.valueOf(vo.getParams("proStatus")));
//			deal.setDealStatus(String.valueOf(vo.getParams("dealStatus")));
//
//			boolean rs = false;
//			if (Validator.isEmpty(deal)) {
//				rs = this.editIdentifyPass(vo, null);
//
//			} else {
//				rs = this.editIdentifyPass(vo, deal);
//			}
//			return rs;
//
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		return false;
//	}

}
